package com.wiscamp.ninechapters.common.rest;

import com.wiscamp.ninechapters.common.core.CollectionHelper;

import java.util.Collection;
import java.util.Objects;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.LongFunction;
import java.util.function.Supplier;

public class AppServiceHelper {
    private AppServiceHelper() {
    }

    public static <E, V> V getById(long id, LongFunction<E> getFunction, Function<E, V> toVOFunction) {
        var entity = getFunction.apply(id);
        if (Objects.nonNull(entity))
            return toVOFunction.apply(entity);
        return null;
    }

    public static <E, V> V getByCode(String code, Function<String, E> getFunction, Function<E, V> toVOFunction) {
        var entity = getFunction.apply(code);
        if (Objects.nonNull(entity))
            return toVOFunction.apply(entity);
        return null;
    }

    public static <E, V> V getByCodeAndId(String code, long id, BiFunction<String, Long, E> getFunction, Function<E, V> toVOFunction) {
        var entity = getFunction.apply(code, id);
        if (Objects.nonNull(entity))
            return toVOFunction.apply(entity);
        return null;
    }

    public static <E, V> Collection<V> getList(Supplier<Collection<E>> getSupplier, Function<E, V> toVOFunction) {
        var entities = getSupplier.get();
        return CollectionHelper.convertToArrayList(entities, toVOFunction);
    }

    public static <E, V> Collection<V> getListByName(String name, Function<String, Collection<E>> getFunction, Function<E, V> toVOFunction) {
        var entities = getFunction.apply(name);
        return CollectionHelper.convertToArrayList(entities, toVOFunction);
    }

    public static <E, V> Collection<V> getListByNameAndId(String name, Long id, BiFunction<String, Long, Collection<E>> getFunction, Function<E, V> toVOFunction) {
        var entities = getFunction.apply(name, id);
        return CollectionHelper.convertToArrayList(entities, toVOFunction);
    }

    public static <P, E, V> PagedEntity<V> getListByPager(P pagination, Function<P, PagedEntity<E>> getFunction, Function<E, V> toVOFunction) {
        var pagedEntity = getFunction.apply(pagination);
        var voList = CollectionHelper.convertToArrayList(pagedEntity.getEntities(), toVOFunction);
        return new PagedEntity<>(pagedEntity.getPages(), pagedEntity.getTotal(), pagedEntity.getSort(), pagedEntity.getField(), voList);
    }

    public static <C, E, V> V create(C createCommand, Function<E, E> createFunction, Function<C, E> fromCommandFunction, Function<E, V> toVOFunction) {
        var entity = fromCommandFunction.apply(createCommand);
        var savedEntity = createFunction.apply(entity);
        if (Objects.nonNull(savedEntity))
            return toVOFunction.apply(savedEntity);
        return null;
    }

    public static <C, E, V> V update(C updateCommand, Function<E, E> updateFunction, Function<C, E> fromCommandFunction, Function<E, V> toVOFunction) {
        var entity = fromCommandFunction.apply(updateCommand);
        var savedEntity = updateFunction.apply(entity);
        if (Objects.nonNull(savedEntity))
            return toVOFunction.apply(savedEntity);
        return null;
    }

    public static Boolean delete(long id, LongFunction<Boolean> deleteFunction) {
        return deleteFunction.apply(id);
    }
}
